package nape.shape;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class Circle extends Shape{
    public var zpp_inner_zn:ZPP_Circle;
    public function new(radius:Float,?localCOM:Vec2,?material:Material,?filter:InteractionFilter){
        try{
            super();
        }
        catch(e:Dynamic){}
        zpp_inner_zn=new ZPP_Circle();
        zpp_inner_zn.outer=this;
        zpp_inner_zn.outer_zn=this;
        zpp_inner=zpp_inner_zn;
        this.radius=radius;
        if(localCOM==null){
            zpp_inner.localCOMx=0;
            zpp_inner.localCOMy=0;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](zpp_inner.localCOMx);
                        ret;
                        #else Math.isNaN(zpp_inner.localCOMx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(zpp_inner.localCOMx)"+") :: "+("vec_set(in n: "+"zpp_inner.localCOM"+",in x: "+"0"+",in y: "+"0"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](zpp_inner.localCOMy);
                        ret;
                        #else Math.isNaN(zpp_inner.localCOMy);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(zpp_inner.localCOMy)"+") :: "+("vec_set(in n: "+"zpp_inner.localCOM"+",in x: "+"0"+",in y: "+"0"+")");
                #end
            };
        };
        else{
            zpp_inner.localCOMx=localCOM.x;
            zpp_inner.localCOMy=localCOM.y;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](zpp_inner.localCOMx);
                        ret;
                        #else Math.isNaN(zpp_inner.localCOMx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(zpp_inner.localCOMx)"+") :: "+("vec_set(in n: "+"zpp_inner.localCOM"+",in x: "+"localCOM.x"+",in y: "+"localCOM.y"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](zpp_inner.localCOMy);
                        ret;
                        #else Math.isNaN(zpp_inner.localCOMy);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(zpp_inner.localCOMy)"+") :: "+("vec_set(in n: "+"zpp_inner.localCOM"+",in x: "+"localCOM.x"+",in y: "+"localCOM.y"+")");
                #end
            };
        };
        if(material==null){
            zpp_inner.material={
                if(ZPP_Material.zpp_pool==null)new ZPP_Material();
                else{
                    var ret=ZPP_Material.zpp_pool;
                    ZPP_Material.zpp_pool=ret.next;
                    ret;
                }
            };
            zpp_inner.material.addShape(this.zpp_inner);
        }
        else this.material=material;
        if(filter==null){
            zpp_inner.filter={
                if(ZPP_InteractionFilter.zpp_pool==null)new ZPP_InteractionFilter();
                else{
                    var ret=ZPP_InteractionFilter.zpp_pool;
                    ZPP_InteractionFilter.zpp_pool=ret.next;
                    ret;
                }
            };
            zpp_inner.filter.addShape(this.zpp_inner);
        }
        else this.filter=filter;
    }
    #if swc@:keep#end public static function copy(circle:Circle){
        if(circle==null)throw "Error: Cannot copy null circle";
        return circle.zpp_inner.copy().circle;
    }
    public var radius(flibget_radius,flibset_radius):Float;
    inline function flibget_radius()return zpp_inner_zn.radius inline function flibset_radius(radius:Float){
        if(zpp_inner.body!=null&&zpp_inner.body.isStatic()&&zpp_inner.body.space!=null)throw "Error: Cannot modifiy radius of Circle contained in static object once added to space";
        if(radius!=this.radius){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](radius);
                ret;
                #else Math.isNaN(radius);
                #end
            }))throw "Error: Circle::radius cannot be NaN";
            if(radius<ZPP_Const.EPSILON)throw "Error: Circle::radius ("+radius+") must be > PR(Const).EPSILON";
            if(radius>ZPP_Const.FMAX)throw "Error: Circle::radius ("+radius+") must be < PR(Const).FMAX";
            zpp_inner_zn.radius=radius;
            zpp_inner_zn.invalidate_radius();
        }
        return this.radius;
    }
    public var rollingFriction(flibget_rollingFriction,flibset_rollingFriction):Bool;
    inline function flibget_rollingFriction()return zpp_inner_zn.rollingFriction inline function flibset_rollingFriction(rollingFriction:Bool){
        zpp_inner_zn.rollingFriction=rollingFriction;
        return this.rollingFriction;
    }
}
